////////////////////////////////////////////////
// DESCRIPTION:
//    HardwareProvider for the Meridian CPU
//
// Legal Notices:
//   Copyright (c) 2008, Telliam Consulting, LLC.
//   All rights reserved.
//
//   Redistribution and use in source and binary forms, with or without modification,
//   are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice, this list
//     of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice, this
//     list of conditions and the following disclaimer in the documentation and/or other
//     materials provided with the distribution.
//   * Neither the name of Telliam Consulting nor the names of its contributors may be
//     used to endorse or promote products derived from this software without specific
//     prior written permission.
//
//   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
//   EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
//   SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
//   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
//   BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
//   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
//   DAMAGE. 
//
using System;
using Microsoft.SPOT.Hardware;

namespace FusionWare.SPOT.Hardware.iMXS
{
    /// <summary>Hardware Provider for Meridian CPU</summary>
    /// <remarks>
    /// This class provides support for standard Meridian CPU pins.
    /// Since the Meridan CPU is used on many different hardware platforms
    /// the exact pin usage is not guranteed for all systems. Therefore,
    /// this class does not implement a static constructor to register itself
    /// with the system. Instead a hardware platform specific derived class
    /// implementation will do that. Often times the derived class adds only
    /// the static constructor, however it may choose to use pins for other
    /// purposes and should report that as needed. 
    /// 
    /// Application level code should NOT use this class directly instead use
    /// the static methods of <see cref="Microsoft.SPOT.Hardware.HardwareProvider"/>
    /// </remarks>
    ///  <example>
    ///  Typical implementation:
    ///  <code source="..\Tahoe\Hardware\HardwareProvider.cs" region="Hardware Provider" lang="cs" title="C#"/>
    ///  </example>
    public class HardwareProvider : Microsoft.SPOT.Hardware.HardwareProvider
    {
        /// <summary>Retrieves pins for the I2C port</summary>
        /// <param name="scl">SCL pin</param>
        /// <param name="sda">SDA Pin</param>
        /// <seealso cref="Microsoft.SPOT.Hardware.HardwareProvider.GetI2CPins"/>
        public override void GetI2CPins(out Cpu.Pin scl, out Cpu.Pin sda)
        {
            scl = Pins.I2C_SCL;
            sda = Pins.I2C_SDA;
        }

        /// <summary>Get Pins for a serial port</summary>
        /// <param name="com">POrt identifier</param>
        /// <param name="rxPin">Receive pin</param>
        /// <param name="txPin">Transmit pin</param>
        /// <seealso cref="Microsoft.SPOT.Hardware.HardwareProvider.GetSerialPins"/>
        public override void GetSerialPins(SerialPort.Serial com, out Cpu.Pin rxPin, out Cpu.Pin txPin)
        {
            switch(com)
            {
            case SerialPort.Serial.COM1:
                rxPin = Pins.UART1_RXD;
                txPin = Pins.UART1_TXD;
                return;

            case SerialPort.Serial.COM2:
                rxPin = Pins.UART2_RXD;
                txPin = Pins.UART2_TXD;
                return;

            default:
                if( ( (int)com & 0xEF00 ) == 0xEF00 )
                {
                    rxPin = Cpu.Pin.GPIO_NONE;
                    txPin = Cpu.Pin.GPIO_NONE;
                    return;
                }
                else
                    throw new NotSupportedException();
            }
        }

        /// <summary>Gets pins for an SPI bus</summary>
        /// <param name="spi_mod">Bus ID</param>
        /// <param name="msk">Clock Pin</param>
        /// <param name="miso">Master-In/Slave-Out Pin</param>
        /// <param name="mosi">Master-Out/Slave-In</param>
        /// <seealso cref="Microsoft.SPOT.Hardware.HardwareProvider.GetSpiPins"/>
        public override void GetSpiPins(SPI.SPI_module spi_mod, out Cpu.Pin msk, out Cpu.Pin miso, out Cpu.Pin mosi)
        {
            if(spi_mod != SPI.SPI_module.SPI1)
                throw new NotSupportedException();

            msk = Pins.SPI_SCLK;
            miso = Pins.SPI_MISO;
            mosi = Pins.SPI_MOSI;
        }
    }
}